/*
 * JJ
 * $Id: gopherd.h,v 1.2 2009/09/05 23:23:45 fred Exp $
 */
#ifndef _GOPHERD_H_
#define _GOPHERD_H_

#define EV_MAX_FREE_SLOTS 500
#define DEFAULT_HOST	"127.0.0.1"
#define DEFAULT_PIDFILE	"/var/run/gopherd.pid"
#define DEFAULT_CHDIR	"/var/gopher"
#define DEFAULT_USER	"gopher"
#define DEFAULT_CHILD_TIMEOUT 20
struct gopher_conn_pool;
typedef struct gopher_conn_pool Gconn;
struct gc_entry;
typedef struct gc_entry Gcent;

struct gevent {
	enum {
	       ST_USED, 
	       ST_FREE} gev_state;
	void	       *gev_handle;
	void	       *gev_data;
	size_t		gev_datalen;
	int		gev_fd;
	struct gevent  *gev_next;
	struct gevent  *gev_prev;
};
typedef struct gevent Gevent;

typedef struct {
	Gevent	*ges_head;
	int	 ges_allocated;
	int	 ges_active;
	int	 ges_lastslot;
	int	 ges_freeslots[EV_MAX_FREE_SLOTS];
	int	 ges_hp_avail;
	void    *ges_hpool;
} Geventset;

struct gopher_server {
	char			 *gs_srv_name;
	struct sockaddr_in	 gs_addr;
	int			 gs_sockfd;
	enum {GS_INIT, 
	      GS_LISTEN, 
	      GS_PROCESS, 
	      GS_IDLE,
	      GS_PARENTW} 	 gs_state;
	pid_t			 gs_child;
	Gconn			*gs_conn;
	Geventset		*gs_evset;
	struct gopher_vserver	*gs_next;
};
typedef struct gopher_server Gserv;

struct gopher_conn_pool {
	Gcent		*gcp_head;
	int		 gcp_conn_cnt;
	void	       (*gcp_new)(Gcent *);
};

struct gc_entry {
	char			*gc_request;
	size_t			 gc_req_siz;
	time_t			 gc_est_time;
	int			 gc_connfd;
	enum {GC_INIT,
	      GC_ACCEPT,
	      GC_PROCESS}	 gc_state;
	struct sockaddr_in	 gc_client;
	Gevent			*gc_event;
#define GC_EXEC		0x1
	int			 gc_flags;
	struct gc_entry		*gc_prev;
	struct gc_entry		*gc_next;
};

struct gopherd_conf {
	char	*gcf_chroot_path;
	char	*gcf_chdir_path;
	char	*gcf_user;
	char	*gcf_host;
	char	*gcf_port;
	char	*gcf_access;
};

#define GLOG_DEBUG	0x1
#define GLOG_ERR	0x2
#define GLOG_CRIT	0x4
#define GLOG_GFW	0x8
#define GLOG_DEFAULT	0xffff

#define GLOG_T_SYSLOG	0x1
#define GLOG_T_FILE	0x2
#define GLOG_FILE_PATH	"logs/access_log"

struct glog {
	int	 l_type;
	FILE	*l_fhandle;
};

#endif /* ! _GOPHERD_H_ */
